﻿namespace UnityEditor.Graphs
{
    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.Diagnostics;
    using System.Runtime.CompilerServices;
    using System.Threading;

    public sealed class TopologicalSort
    {
        private static Graph s_Graph;
        private static Dictionary<Node, NodeState> s_NodeStates;
        private static List<Node> s_SortedNodes;

        private TopologicalSort()
        {
        }

        public static void Sort(Graph g)
        {
            s_Graph = g;
            s_SortedNodes = new List<Node>();
            s_NodeStates = new Dictionary<Node, NodeState>();
            foreach (Node node in g.nodes)
            {
                Visit(node);
            }
        }

        private static void Visit(Node n)
        {
            if (!s_NodeStates.ContainsKey(n))
            {
                s_NodeStates[n] = NodeState.Visited;
                IEnumerator<Edge> enumerator = n.outputEdges.GetEnumerator();
                try
                {
                    while (enumerator.MoveNext())
                    {
                        Edge current = enumerator.Current;
                        Visit(current.toSlot.node);
                    }
                }
                finally
                {
                    if (enumerator == null)
                    {
                    }
                    enumerator.Dispose();
                }
                s_SortedNodes.Add(n);
            }
        }

        public static IEnumerable<Node> deadNodes
        {
            get
            {
                return new <>c__Iterator0 { $PC = -2 };
            }
        }

        public static List<Node> SortedNodes
        {
            get
            {
                return s_SortedNodes;
            }
        }

        [CompilerGenerated]
        private sealed class <>c__Iterator0 : IEnumerator, IDisposable, IEnumerable<Node>, IEnumerator<Node>, IEnumerable
        {
            internal Node $current;
            internal int $PC;
            internal List<Node>.Enumerator <$s_57>__0;
            internal Node <n>__1;

            [DebuggerHidden]
            public void Dispose()
            {
                uint num = (uint) this.$PC;
                this.$PC = -1;
                switch (num)
                {
                    case 1:
                        try
                        {
                        }
                        finally
                        {
                            this.<$s_57>__0.Dispose();
                        }
                        break;
                }
            }

            public bool MoveNext()
            {
                uint num = (uint) this.$PC;
                this.$PC = -1;
                bool flag = false;
                switch (num)
                {
                    case 0:
                        if (TopologicalSort.s_Graph != null)
                        {
                            this.<$s_57>__0 = TopologicalSort.s_Graph.nodes.GetEnumerator();
                            num = 0xfffffffd;
                            break;
                        }
                        goto Label_00D2;

                    case 1:
                        break;

                    default:
                        goto Label_00D2;
                }
                try
                {
                    while (this.<$s_57>__0.MoveNext())
                    {
                        this.<n>__1 = this.<$s_57>__0.Current;
                        if (!TopologicalSort.s_SortedNodes.Contains(this.<n>__1))
                        {
                            this.$current = this.<n>__1;
                            this.$PC = 1;
                            flag = true;
                            return true;
                        }
                    }
                }
                finally
                {
                    if (!flag)
                    {
                    }
                    this.<$s_57>__0.Dispose();
                }
                this.$PC = -1;
            Label_00D2:
                return false;
            }

            [DebuggerHidden]
            public void Reset()
            {
                throw new NotSupportedException();
            }

            [DebuggerHidden]
            IEnumerator<Node> IEnumerable<Node>.GetEnumerator()
            {
                if (Interlocked.CompareExchange(ref this.$PC, 0, -2) == -2)
                {
                    return this;
                }
                return new TopologicalSort.<>c__Iterator0();
            }

            [DebuggerHidden]
            IEnumerator IEnumerable.GetEnumerator()
            {
                return this.System.Collections.Generic.IEnumerable<UnityEditor.Graphs.Node>.GetEnumerator();
            }

            Node IEnumerator<Node>.Current
            {
                [DebuggerHidden]
                get
                {
                    return this.$current;
                }
            }

            object IEnumerator.Current
            {
                [DebuggerHidden]
                get
                {
                    return this.$current;
                }
            }
        }

        private enum NodeState
        {
            Visited
        }
    }
}

